<template>
  <page-view
    :backNavigation="{
      onBack: handleBack
    }"
  >
    <div class="page-header-index-wide">
      <a-spin :spinning="loading || loadingParty">
        <a-card
          :bordered="false"
          :bodyStyle="{ padding: '16px 0', height: '100%' }"
          :style="{ minHeight: `${layoutContentHeight - pageHeaderHeight - 24}px` }"
        >
          <div class="account-settings-info-main">
            <div class="account-settings-info-left">
              <div class="avatar-wrap">
                <a-avatar class="avatar" :size="150" :src="avatarUrl | imgURLFilter">
                  <a-spin tip="上传中" :spinning="uploading">
                    <a-icon slot="indicator" type="loading" style="font-size: 24px" spin />
                  </a-spin>
                </a-avatar>
                <a-upload
                  name="file"
                  :show-upload-list="false"
                  accept="image/jpeg,image/png"
                  :customRequest="customRequest"
                  :before-upload="beforeUpload"
                  @change="handleChange"
                >
                  <a-button icon="upload">{{ $t('modules.org.changeAvatar') }}</a-button>
                </a-upload>
              </div>
            </div>
            <div class="account-settings-info-right">
              <div class="account-settings-info-view">
                <a-form :form="form" :label-col="{ span: 2 }" :wrapper-col="{ span: 12 }" @submit="handleSubmit">
                  <a-form-item :label="$t('modules.org.jobNumber')">
                    <s-input
                      v-decorator="[
                        'jobNumber',
                        {
                          validateFirst: true,
                          rules: [
                            { required: true, message: '请输入工号！', transform: value => value && value.trim() },
                            { validator: validator.jobNumberValidator }
                          ]
                        }
                      ]"
                      :limit="32"
                      :spell-check="false"
                      autocomplete="off"
                    />
                  </a-form-item>
                  <a-form-item :label="$t('modules.org.personName')">
                    <s-input
                      v-decorator="[
                        'name',
                        {
                          rules: [
                            { required: true, message: '请输入姓名！', transform: value => value && value.trim() }
                          ]
                        }
                      ]"
                      :limit="64"
                      :spell-check="false"
                      autocomplete="off"
                    />
                  </a-form-item>
                  <a-form-item :label="$t('modules.org.gender')">
                    <a-radio-group name="gender" v-decorator="['gender', { initialValue: 1 }]">
                      <a-radio :value="1">{{ $t('modules.org.male') }}</a-radio>
                      <a-radio :value="0">{{ $t('modules.org.female') }}</a-radio>
                    </a-radio-group>
                  </a-form-item>
                  <a-form-item :label="$t('modules.org.email')">
                    <s-input
                      v-decorator="[
                        'email',
                        {
                          validateFirst: true,
                          rules: [
                            { type: 'email', message: '请输入正确的邮箱地址', transform: val => val && val.trim() },
                            { validator: validator.emailValidator }
                          ]
                        }
                      ]"
                      :limit="128"
                      :spell-check="false"
                      autocomplete="off"
                    />
                  </a-form-item>
                  <a-form-item :label="$t('modules.org.phoneNumber')">
                    <a-input
                      v-decorator="[
                        'telephone',
                        {
                          validateFirst: true,
                          rules: [
                            { required: true, message: '请输入手机号！', transform: value => value && value.trim() },
                            { pattern: isTel, message: '请输入 11 位手机号！' },
                            { validator: validator.telephoneValidator }
                          ]
                        }
                      ]"
                      :spell-check="false"
                      autocomplete="off"
                    >
                      <a-select
                        slot="addonBefore"
                        style="width: 70px"
                        v-decorator="['phoneRegion', { initialValue: '86' }]"
                      >
                        <a-select-option value="86">
                          +86
                        </a-select-option>
                      </a-select>
                    </a-input>
                  </a-form-item>
                  <a-form-item :label="$t('modules.org.dept')">
                    <a-tree-select
                      style="width: 100%"
                      :dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
                      :treeData="treeData"
                      multiple
                      treeDefaultExpandAll
                      dropdownMatchSelectWidth
                      v-decorator="[
                        'orgId',
                        {
                          rules: [{ required: true, message: '请选择部门！' }]
                        }
                      ]"
                    >
                      <span slot="title" slot-scope="p" :title="p.name">
                        {{ p.name }}
                      </span>
                    </a-tree-select>
                  </a-form-item>
                  <a-form-item :label="$t('modules.org.position')">
                    <s-input v-decorator="['position']" :limit="128" :spell-check="false" autocomplete="off" />
                  </a-form-item>
                  <a-form-item :label="$t('modules.org.hidNo')">
                    <s-textarea
                      v-decorator="[
                        'hidNo',
                        {
                          validateFirst: true,
                          rules: [{ validator: validator.hidNoValidator }]
                        }
                      ]"
                      :limit="500"
                    />
                  </a-form-item>
                  <a-form-item class="footer" :wrapper-col="{ offset: 2, span: 12 }">
                    <a-button style="margin-right: 8px;" @click="handleBack">{{ $t('common.cancel') }}</a-button>
                    <a-button v-action:save type="primary" html-type="submit" :loading="confirmLoading">{{
                      $t('common.save')
                    }}</a-button>
                  </a-form-item>
                </a-form>
              </div>
            </div>
          </div>
        </a-card>
      </a-spin>
    </div>
  </page-view>
</template>

<script>
import { readAllOrg, createUser, updateUser, readUser, userUnique } from '@/api/structure';
import { PageView } from '@/layouts';
import { SInput, STextarea } from '@/components';
import { mixinDevice, layoutMixin, asyncValidateMixin } from '@/utils/mixin';
import { uploadFile } from '@/api/common';
import { setArrayToTree } from '@/utils/util';
import { UserPickerOptions } from '@/components/UserPicker/options';
import { isTel } from '@/utils/regExp';

export default {
  name: 'StructureUser',
  components: {
    PageView,
    SInput,
    STextarea
  },
  mixins: [mixinDevice, layoutMixin, asyncValidateMixin],
  data() {
    return {
      isTel,
      userId: null,
      user: {},
      uploading: false,
      avatarUrl: '',
      form: this.$form.createForm(this),
      loadingParty: false,
      partyList: [],
      confirmLoading: false,
      loading: false,
      // 可见应用
      appList: [],
      // 从其它路由跳转过来还是直接打开
      routerCanBack: false
    };
  },
  computed: {
    treeData() {
      const partyList = this.partyList;
      partyList.forEach(party => {
        party.scopedSlots = { title: 'title' };
        party.value = party.id;
      });

      // 组织机构部门树状结构
      const tree = setArrayToTree({
        ...UserPickerOptions,
        data: partyList,
        collection: 'children'
      });

      return tree;
    },
    // 部门全路径
    orgMatched() {
      if (!this.user || !this.user.orgIds) return [];

      const orgMaps = [];
      this.user.orgIds.forEach(id => {
        const tree = [];
        let party = this.partyList.find(item => item.id === id);
        while (party) {
          tree.unshift(party);
          party = this.partyList.find(item => item.id === party[UserPickerOptions.pid]);
        }
        orgMaps.unshift(tree);
      });

      const orgNames = orgMaps.map(list => list.map(org => org.name).join('/'));
      return orgNames;
    }
  },
  created() {
    this.$_asyncValidateMixin_init([
      {
        fieldName: 'jobNumber',
        caller: userUnique,
        extraParams: this.getExtraParams
      },
      {
        fieldName: 'email',
        caller: userUnique,
        extraParams: this.getExtraParams
      },
      {
        fieldName: 'telephone',
        caller: userUnique,
        extraParams: this.getExtraParams
      },
      {
        fieldName: 'hidNo',
        caller: userUnique,
        extraParams: this.getExtraParams
      }
    ]);
  },
  mounted() {
    this.getAllParty();
    const { id } = this.$route.params;
    if (id) {
      this.getUserInfo();
    }
  },
  methods: {
    // 编辑页获取用户信息
    async getUserInfo() {
      const { id } = this.$route.params;
      const { type, orgId } = this.$route.query;
      const { setFieldsValue } = this.form;
      this.userId = id;
      this.loading = true;

      const res = await readUser({ id });
      this.loading = false;
      if (res.code === 'sso.ok') {
        const { avatar, jobNumber, name, gender, email, telephone, phoneRegion, orgIds, hidNo, position } = res.data;
        this.avatarUrl = avatar;
        setFieldsValue({
          orgId: orgIds,
          email: email || undefined,
          hidNo: hidNo || undefined,
          position: position || undefined,
          jobNumber,
          name,
          gender,
          telephone,
          phoneRegion
        });
        this.user = { ...res.data };
      }
    },
    // 获取所有部门
    async getAllParty() {
      this.loadingParty = true;
      const res = await readAllOrg();
      if (res.code === 'sso.ok') {
        this.partyList = res.data || [];
        const { orgId } = this.$route.query;
        const { id } = this.$route.params;
        if (!id && orgId) {
          // 新建人员带上的部门
          this.form.setFieldsValue({
            orgId: [Number(orgId)]
          });
        }
      }
      this.loadingParty = false;
    },
    beforeUpload(file) {
      const isLtSize = file.size / 1024 / 1024 < 5;
      if (!isLtSize) {
        this.$message.error('图片大小不能超过 5MB!');
      }
      return isLtSize;
    },
    handleChange(info) {
      const { status } = info.file;
      if (status === 'uploading') {
        this.uploading = true;
      } else if (status === 'done') {
        this.uploading = false;
        const { response } = info.file;
        this.avatarUrl = response.data;
      } else if (status === 'error') {
        this.uploading = false;
      }
    },
    // 上传文件
    async customRequest({ file, filename, onSuccess, onError }) {
      const formData = new FormData();
      formData.append(filename, file);
      const res = await uploadFile(formData);
      if (res.code === 'sso.ok') {
        onSuccess(res);
      } else {
        onError();
      }
    },
    // 保存
    handleSubmit(e) {
      e.preventDefault();
      const {
        form: { validateFields, getFieldsValue }
      } = this;
      this.confirmLoading = true;
      // 远程校验通过的字段不参与最终校验
      // 最终校验通过后，values 不包含未参与最终校验的远程字段，需要主动获取所有字段值
      const req = getFieldsValue();
      const fieldNames = this.$_asyncValidateMixin_fieldsFilter();
      validateFields(fieldNames, async (errors, values) => {
        if (!errors) {
          for (let key in req) {
            if (['jobNumber', 'name', 'email', 'telephone', 'position', 'hidNo'].includes(key)) {
              req[key] = req[key] ? req[key].trim() : '';
            }
          }

          if (this.userId) {
            req.id = this.userId;
          }

          // 头像
          if (this.avatarUrl) {
            req.avatar = this.avatarUrl;
          }

          const res = this.userId ? await updateUser(req) : await createUser(req);
          this.confirmLoading = false;
          if (res.code === 'sso.ok') {
            this.handleBack();
            this.$message.success(res.message);
          }
        } else {
          this.confirmLoading = false;
        }
      });
    },
    // 返回列表页面
    handleBack() {
      if (this.routerCanBack) {
        this.$router.back();
      } else {
        this.$router.push({ name: 'structureList' });
      }
    },
    // 表单校验额外参数
    getExtraParams() {
      return {
        id: this.userId
      };
    }
  },
  beforeRouteEnter(to, from, next) {
    const fromRoute = from.name;
    next(vm => {
      vm.routerCanBack = !!fromRoute;
    });
  }
};
</script>

<style lang="less" scoped>
.account-settings-info-main {
  width: 100%;
  display: flex;
  height: 100%;
  overflow: auto;

  .account-settings-info-left {
    width: 224px;
    .avatar-wrap {
      text-align: center;
      .avatar {
        margin-bottom: 24px;
      }
    }
  }

  .account-settings-info-right {
    flex: 1 1;
    padding: 8px 40px;

    .account-settings-info-view {
      padding-top: 12px;
    }
  }
}
.footer {
  text-align: right;
}
</style>
